package health_system.health_system.repository;

import health_system.health_system.entity.Moment;
import health_system.health_system.entity.MomentLike;
import health_system.health_system.entity.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface MomentLikeRepository extends JpaRepository<MomentLike, Long> {
    
    // Find like by user and moment
    Optional<MomentLike> findByUserAndMoment(User user, Moment moment);
    
    // Find all likes for a moment
    List<MomentLike> findByMomentOrderByCreatedAtDesc(Moment moment);
    
    // Find with pagination
    Page<MomentLike> findByMomentOrderByCreatedAtDesc(Moment moment, Pageable pageable);
    
    // Find all moments liked by a user
    @Query("SELECT ml.moment FROM MomentLike ml WHERE ml.user = :user ORDER BY ml.createdAt DESC")
    List<Moment> findMomentsLikedByUser(@Param("user") User user);
    
    // Find with pagination
    @Query("SELECT ml.moment FROM MomentLike ml WHERE ml.user = :user ORDER BY ml.createdAt DESC")
    Page<Moment> findMomentsLikedByUser(@Param("user") User user, Pageable pageable);
    
    // Check if user has liked a moment
    boolean existsByUserAndMoment(User user, Moment moment);
    
    // Delete like
    void deleteByUserAndMoment(User user, Moment moment);
    
    // Count likes for a moment
    Long countByMoment(Moment moment);
    
    // Count likes by user
    Long countByUser(User user);
    
    // Find users who liked a moment
    @Query("SELECT ml.user FROM MomentLike ml WHERE ml.moment = :moment ORDER BY ml.createdAt DESC")
    List<User> findUsersWhoLikedMoment(@Param("moment") Moment moment);
    
    // Find with pagination
    @Query("SELECT ml.user FROM MomentLike ml WHERE ml.moment = :moment ORDER BY ml.createdAt DESC")
    Page<User> findUsersWhoLikedMoment(@Param("moment") Moment moment, Pageable pageable);
    
    // Find moments with most likes in user's visible moments
    @Query("SELECT m, COUNT(ml) FROM Moment m LEFT JOIN m.likes ml WHERE " +
           // Same visibility filters as in MomentRepository
           "(" +
           "(m.visibility = 'PUBLIC') OR " +
           "(m.user = :viewer) OR " +
           "(m.visibility = 'FRIENDS' AND " +
           "EXISTS (SELECT f FROM Friendship f WHERE " +
           "((f.requester = m.user AND f.addressee = :viewer) OR " +
           "(f.requester = :viewer AND f.addressee = m.user)) AND f.status = 'ACCEPTED')) OR " +
           "(m.visibility = 'CUSTOM' AND :viewer MEMBER OF m.visibleToUsers)" +
           ") " +
           "GROUP BY m ORDER BY COUNT(ml) DESC")
    List<Object[]> findMomentsWithMostLikesVisibleToUser(@Param("viewer") User viewer, Pageable pageable);
    
    // Find most recently liked moments by a user's friends
    @Query("SELECT ml.moment FROM MomentLike ml WHERE ml.user IN " +
           "(SELECT CASE WHEN f.requester = :user THEN f.addressee ELSE f.requester END " +
           "FROM Friendship f WHERE (f.requester = :user OR f.addressee = :user) AND f.status = 'ACCEPTED') " +
           "AND ml.moment.visibility IN ('PUBLIC', 'FRIENDS') " +
           "ORDER BY ml.createdAt DESC")
    List<Moment> findRecentlyLikedMomentsByFriends(@Param("user") User user, Pageable pageable);
} 